package com.ygqh.baby.service.impl;

import com.ygqh.baby.ao.*;
import com.ygqh.baby.constant.RedisConstant;
import com.ygqh.baby.mapper.YgAgentMapper;
import com.ygqh.baby.model.YgUserAddressModel;
import com.ygqh.baby.po.*;
import com.ygqh.baby.redis.RedisDao;
import com.ygqh.baby.service.*;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.YgStringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class YgAgentServiceImpl implements YgAgentService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private YgAgentMapper ygAgentMapper;
	@Autowired
	private YgOrderService ygOrderService;
	@Autowired
	private YgUserService ygUserService;
	@Autowired
	private YgUserAddressService ygUserAddressService;
	@Autowired
	private ScheduleJobService scheduleJobService;
	@Autowired
	private SmsService smsService;
	@Autowired
	private YgInformService ygInformService;
	@Autowired
	private YgCouponService ygCouponService;
	@Autowired
	private RedisDao redisDao;
	@Autowired
    private YgRechargeMemberRecordService ygRechargeMemberRecordService;
	@Autowired
    private YgPlatformService ygPlatformService;
	@Autowired
    private YgPayService ygPayService;
	@Autowired
	private YgAgentLevelService ygAgentLevelService;

	@Override
	public List<YgAgent> find() {
		YgAgentExample example = new YgAgentExample();
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
		return ygAgentMapper.selectByExample(example);
	}

	@Override
	public int findCount() {
		YgAgentExample example = new YgAgentExample();
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
		return ygAgentMapper.countByExample(example);
	}

	@Override
	public YgAgent findById(Long id) {
		return ygAgentMapper.selectByPrimaryKey(id);
	}

	@Override
	public int save(YgAgent ygAgent) {
		return ygAgentMapper.insertSelective(ygAgent);
	}

	@Override
	public int update(YgAgent ygAgent) {
		return ygAgentMapper.updateByPrimaryKeySelective(ygAgent);
	}

	@Override
	public ResultSet<YgAgent> search(QueryInfo queryInfo, String nickName, String userName, CheckStatus checkStatus, Date startDate, Date endDate,
			Date orderStartDate, Date orderEndDate) {
		int count = ygAgentMapper.countSuper(nickName, userName, checkStatus, startDate, endDate, orderStartDate, orderEndDate);
		if (count == 0) {
			return new ResultSet<>();
		}
		List<YgAgent> list = ygAgentMapper.selectSuper(queryInfo, nickName, userName, checkStatus, startDate, endDate, orderStartDate, orderEndDate);
		return new ResultSet<>(count, list);
	}

	@Override
	public int deleteSoft(Long[] ids) {
		Assert.notEmpty(ids);
		YgAgentExample example = new YgAgentExample();
		example.createCriteria().andIdIn(Arrays.asList(ids));
		YgAgent record = new YgAgent();
		record.setStatus(DataStatus.Delete);

		return ygAgentMapper.updateByExampleSelective(record, example);
	}

	@Override
	public int deleteSoft(Long id) {
		return this.deleteSoft(new Long[] { id });
	}

	@Override
	public int saveOrUpdate(YgAgent ygAgent) {
		int r;
		if (ygAgent.getId() != null) {
			r = this.update(ygAgent);
		} else {
			r = this.save(ygAgent);
		}
		return r;
	}

	@Override
	public int updateCheckStatus(Long id, CheckStatus checkStatus, String checkRemark, String checkBy, Date checkTime) {
		YgAgent agent = new YgAgent();
		agent.setId(id);
		agent.setCheckBy(checkBy);
		agent.setCheckStatus(checkStatus);
		agent.setCheckTime(checkTime);
		agent.setCheckRemark(checkRemark);
		return ygAgentMapper.updateByPrimaryKeySelective(agent);
	}

	@Override
	public YgAgent findByUserIdAndPass(Long userId, UserType userType) {
		List<YgAgent> agentList = this.findYgAgentList(userId, userType, CheckStatus.Pass, null);
		if (CollectionUtils.isNotEmpty(agentList)) {
			return agentList.get(0);
		}
		return null;
	}

	private List<YgAgent> findYgAgentList(Long userId, UserType userType, CheckStatus checkStatus, String orderByClause) {
		YgAgentExample example = new YgAgentExample();
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name()).andUserIdEqualTo(userId);
		if (userType != null) {
			example.getOredCriteria().get(0).andUserTypeEqualTo(userType.name());
		}
		if (checkStatus != null) {
			example.getOredCriteria().get(0).andCheckStatusEqualTo(checkStatus.name());
		}
		if (StringUtils.isNotBlank(orderByClause)) {
			example.setOrderByClause(orderByClause);
		}
		return ygAgentMapper.selectByExample(example);
	}

	@Override
	public YgAgent findAgentInfo(Long id) {
		return ygAgentMapper.findAgentInfo(id);
	}

	@Override
	public boolean validateAgentStatus(Long userId) {

		Date endDate = DateConvertUtils.getMonthStartDate(new Date());
		Date startDate = DateConvertUtils.getMonthStartDate(DateConvertUtils.addMonth(endDate, -3));
		List<Map<String, Object>> totalPriceByMonth = ygOrderService.getTotalPriceWithMonth(userId, startDate, endDate);
		BigDecimal totalPrice = new BigDecimal("0.00");
		if (CollectionUtils.isNotEmpty(totalPriceByMonth)) {
			for (Map<String, Object> map : totalPriceByMonth) {
				totalPrice = totalPrice.add(new BigDecimal(map.get("totalPrice").toString()));
			}
		}
		return totalPrice.compareTo(new BigDecimal("2000.00")) >= 0;
	}

	@Override
	public Message saveGroupHead(Long userId, String createBy) {
		if (userId == null) {
			return Message.error("请选择要设置为团长的用户");
		}
		YgAgent groupAgent = this.findByUserIdAndPass(userId, UserType.Group);
		if (groupAgent != null) {
			return Message.error("要操作的用户已经是团长");
		}
		// 校验该用户是否为代理
		YgAgent agent = this.findByUserIdAndPass(userId, UserType.UserAgent);
        YgUser user = ygUserService.findById(userId);
        Date now = new Date();
        if (agent != null) {
		    // 先取消代理身份
            YgAgent record = new YgAgent();
            record.setId(agent.getId());
            record.setCancelBy(createBy);
            record.setCancelTime(now);
            record.setCheckStatus(CheckStatus.Cancel);
            this.update(record);
        } else {
		    // 初始化团长信息
            agent = new YgAgent();
            agent.setUserId(userId);
            YgUserAddressModel addressModel = ygUserAddressService.findDefaultUserAddress(userId, null);
            if (addressModel != null) {
                agent.setTrueName(addressModel.getReceiver());
                agent.setAddress(addressModel.getProvinceName() + addressModel.getCityName() + addressModel.getAreaName() + addressModel.getAddress());
            } else {
                agent.setTrueName(user.getUserName());
                agent.setAddress("");
            }
            agent.setChildAge("");
            agent.setFromChannel("其他");
            agent.setAdvantage("");
            agent.setIdentityCard("");
            agent.setEmail("");
            agent.setCheckStatus(CheckStatus.Pass);
        }
        agent.setUserType(UserType.Group);
		agent.setCheckTime(now);
		agent.setCreateTime(now);
		agent.setCheckBy(createBy);
		this.save(agent);
		YgUser ygUser = new YgUser();
		ygUser.setId(userId);
		ygUser.setUserType(UserType.Group);
		// 团长标签的设定
		ygUser.setGroupTag(user.getUserName());
        ygUser.setUpdateTime(now);
		ygUserService.updateUserInfo(ygUser);
        return Message.success(agent);
	}

	@Override
	public Message createCancelJob(Long userId, String cancelBy, UserType userType) {
		String operation = userType.equals(UserType.Group) ? "团长" : "代理";
		if (userId == null) {
			return Message.error("请选择要取消" + operation + "的用户");
		}
		YgAgent dbAgent = this.findValidByUserId(userId, userType);
		if (dbAgent == null) {
			return Message.error("要操作的用户不是" + operation);
		}
		if (CheckStatus.WaitingCancel.equals(dbAgent.getCheckStatus())) {
			return Message.error("要操作的用户正在取消中", null);
		}
		YgAgent agent = new YgAgent();
		agent.setId(dbAgent.getId());
		agent.setUpdateBy(cancelBy);
		agent.setUpdateTime(new Date());
		agent.setCheckStatus(CheckStatus.WaitingCancel);
		this.update(agent);
        return scheduleJobService.addCancelAgentJob(agent.getId(), agent.getUpdateTime(), cancelBy);
	}

	@Override
	public YgAgent findByRecent(Long userId, UserType userType) {
		List<YgAgent> ygAgents = this.findYgAgentList(userId, userType, null, "create_time DESC");
		if (CollectionUtils.isNotEmpty(ygAgents)) {
			return ygAgents.get(0);
		}
		return null;
	}

	@Override
	public void cancelAgent(Long agentId, String cancelBy) {
		YgAgent ygAgent = this.findById(agentId);
		if (ygAgent == null || !CheckStatus.WaitingCancel.equals(ygAgent.getCheckStatus())) {
			return;
		}
        cancelAgent(ygAgent, cancelBy, "");
	}

	@Override
	public Message deleteCancelOperation(Long userId, String updateBy) {
		List<YgAgent> findYgAgentList = this.findYgAgentList(userId, null, CheckStatus.WaitingCancel, "create_time DESC");
		if (CollectionUtils.isEmpty(findYgAgentList)) {
			return Message.error("");
		}
		YgAgent ygAgent = findYgAgentList.get(0);
		YgAgent agent = new YgAgent();
		agent.setId(ygAgent.getId());
		agent.setUpdateBy(updateBy);
		agent.setUpdateTime(new Date());
		agent.setCheckStatus(CheckStatus.Pass);
		int row = this.update(agent);
		if (row == 1) {
			YgQuartzJob qj = YgQuartzJob.CancelAgent;
			String jobName = qj.getJobName(ygAgent.getId().toString());
			String jobGroup = qj.getJobGroup();
			return scheduleJobService.deleteJob(jobName, jobGroup, updateBy);
		}
		return Message.error("请稍后重试");
	}

	@Override
	public List<YgAgent> findAgentByTime(Date startDate, Date endDate, CheckStatus checkStatus) {
		return ygAgentMapper.findAgentByTime(startDate, endDate, checkStatus);
	}

	@Override
	public List<YgAgent> findByCheckStatus(List<String> checkStatus) {
		YgAgentExample example = new YgAgentExample();
		YgAgentExample.Criteria criteria = example.createCriteria();
		if (checkStatus != null && checkStatus.size() > 0) {
			criteria.andCheckStatusIn(checkStatus);
		}
		criteria.andStatusEqualTo(DataStatus.Valid.name());
		return ygAgentMapper.selectByExample(example);
	}

	@Override
	public YgAgent findValidByUserId(Long userId, UserType userType) {
		Assert.notNull(userId);
		Assert.notNull(userType);
		YgAgentExample example = new YgAgentExample();
		YgAgentExample.Criteria criteria = example.createCriteria();
		criteria.andUserIdEqualTo(userId)
				.andUserTypeEqualTo(userType.name())
				.andCheckStatusIn(Arrays.asList(CheckStatus.Pass.name(), CheckStatus.WaitingCancel.name()))
				.andStatusEqualTo(DataStatus.Valid.name());
		List<YgAgent> list = ygAgentMapper.selectByExample(example);
		if (CollectionUtils.isEmpty(list)) {
			return null;
		}
		YgAgent agent = list.get(0);
		if (agent.getLevelId() != null) {
			agent.setAgentLevel(ygAgentLevelService.findById(agent.getLevelId()));
		}
		return agent;
	}

	@Override
	public ResultSet<Map<String, Object>> searchUserAgentReport(QueryInfo queryInfo) {
		int total = ygAgentMapper.countByUserAgentReport();
		if (total == 0) {
			return new ResultSet<>();
		}
		List<Map<String, Object>> result = ygAgentMapper.selectByByUserAgentReport(queryInfo);
		return new ResultSet<>(total, result);
	}

	@Override
	public void rechargeUserAgent(YgUser user, String handler, String platformNo) {
		// 添加会员记录表
		YgAgent agent = new YgAgent();
		agent.setUserId(user.getId());
		agent.setUserType(UserType.UserAgent);
		agent.setTelPhone(user.getTelPhone());
		agent.setTrueName(user.getNickName());
		agent.setCheckStatus(CheckStatus.Pass);
		agent.setCheckTime(new Date());
		agent.setCreateTime(agent.getCheckTime());
		agent.setPlatformNo(platformNo);
		agent.setCheckRemark(handler);
		this.save(agent);
		// 更新用户类型
		ygUserService.updateUserType(UserType.UserAgent, user.getId());
		System.out.println("用户【" + user.getUserName() + "】成为代理（壹家店）");
		// 发送站内消息
		ygInformService.asyncSendInform(user.getId(), null, InformType.RechargeMember, handler);

		// 发优惠券
		try {
			ygCouponService.receiveCouponBatch(redisDao.get(RedisConstant.USERAGENT_PAYSUCCESS_COUPON), user);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

    @Override
    public Message cancelUserAgent(Long userId, String handler, UserType userType, String remark, BigDecimal refundPrice) {
        String operation = userType.equals(UserType.Group) ? "团长" : "代理";
        if (userId == null) {
            return Message.error("请选择要取消" + operation + "的用户");
        }
        YgAgent dbAgent = this.findValidByUserId(userId, userType);
        if (dbAgent == null) {
            return Message.error("要操作的用户不是" + operation);
        }
        if (UserType.UserAgent.equals(userType) && refundPrice != null && refundPrice.compareTo(BigDecimal.ZERO) > 0) {
            // 查询是否为购买资格
            ResultSet<YgRechargeMemberRecord> resultSet = ygRechargeMemberRecordService.
                    searchRecordByUserId(userId, CodeType.RechargeAG);
            if (CollectionUtils.isNotEmpty(resultSet.getResult())) {
                YgRechargeMemberRecord record = resultSet.getResult().get(0);
                if (record.getRefundTime() == null) {
                    if (record.getPaidPrice().compareTo(refundPrice) < 0) {
                        return Message.error("退款金额超出实际支付金额，" +
                                "实际支付金额" + record.getPaidPrice() + "元", null);
                    }
                    // 发起微信退款
                    YgPlatform platform = ygPlatformService.findByPlatformNo(record.getPlatformNo(), record.getAppType());
                    try {
                        ygPayService.refund(platform, record.getAppType(), record.getPayType(), record.getPaymentCode().toString(),
                                record.getPaymentCode().toString(), refundPrice, record.getPaidPrice());
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                        return Message.error("自动退款异常", null);
                    }
                    ygRechargeMemberRecordService.refundRecord(record.getId(), handler, "实际退款金额" + refundPrice.toString());
                }
            }
        }
        cancelAgent(dbAgent, handler, remark);
        return Message.success(null);
    }

    @Override
    public List<YgAgent> findByLevelId(Long levelId) {
		YgAgentExample example = new YgAgentExample();
		example.createCriteria().andLevelIdEqualTo(levelId)
				.andUserTypeEqualTo(UserType.UserAgent.name())
				.andCheckStatusIn(Arrays.asList(CheckStatus.Pass.name(), CheckStatus.WaitingCancel.name()))
				.andStatusEqualTo(DataStatus.Valid.name());
        return ygAgentMapper.selectByExample(example);
    }

    private void cancelAgent(YgAgent ygAgent, String cancelBy, String remark) {
        YgAgent agent = new YgAgent();
        agent.setId(ygAgent.getId());
        agent.setCancelBy(cancelBy);
        agent.setCancelTime(new Date());
        agent.setCheckStatus(CheckStatus.Cancel);
        agent.setRemark(remark);
        int row = this.update(agent);
        if (row == 1) {
            YgUser user = ygUserService.findById(ygAgent.getUserId());
            ygUserService.updateAgentToCancelByUserId(ygAgent.getUserId());
            if (YgStringUtils.isChinaPhoneLegal(user.getUserName())) {
                String operation = ygAgent.getUserType().equals(UserType.Group) ? "团长" : "代理";
                smsService.sendSms(user.getUserName(), "您好，您的" + operation + "资格已取消，有疑问请联系壹果客服。");
            }
        }
    }
}
